#include "pch.h"
#include "objectId.h"
#include <random>
#include <sstream>

namespace jm
{

    objectId::objectId(const u8_string& id) noexcept
    {
        m_id = id;
    }

    objectId::objectId(const objectId& id) noexcept
    {
        m_id = id.m_id;
    }

    objectId::objectId(objectId&& id) noexcept
    {
        m_id = std::move(id.m_id);
    }

    objectId& objectId::operator=(const objectId& id) noexcept
    {
        m_id = id.m_id;
        return *this;
    }

    objectId& objectId::operator=(objectId&& id) noexcept
    {
        m_id = std::move(id.m_id);
        return *this;
    }

    bool objectId::operator<(const objectId& id) const noexcept
    {
        return m_id < id.m_id;
    }

    bool objectId::isValid() const
    {
        return (m_id.empty() || m_id == "0") ? false : true;
    }

    // https://lowrey.me/guid-generation-in-c-11/
    unsigned char random_char()
    {
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0, 255);
        return static_cast<unsigned char>(dis(gen));
    }

    std::string generate_hex(const unsigned int len)
    {
        std::stringstream ss;
        for (unsigned int i = 0; i < len; i++)
        {
            auto rc = random_char();
            std::stringstream hexstream;
            hexstream << std::hex << int(rc);
            auto hex = hexstream.str();
            ss << (hex.length() < 2 ? '0' + hex : hex);
        }
        return ss.str();
    }

    objectId objectId::create() noexcept
    {
        return objectId(generate_hex(16));
    }
}
